#include "tasklistmodelutil.h"
#include "../tasktop4qtcreator/repository.h"
#include "../tasktop4qtcreator/tasklistconstants.h"
#include "../tasktop4qtcreator/taskhandle.h"
#include <QPointer>
#include "ticket.h"
#include <QxtCore/QxtLogger>

TasklistModelUtil::TasklistModelUtil(QObject *parent) :
    QObject(parent)
{
}

TaskListRoot* TasklistModelUtil::rootFromQuery(QString repoUrl, QString queryLabel)
{
    QPointer<TaskListRoot> root = new TaskListRoot();
    QList<TaskContainerHandle*> containers;
    containers.append(TasklistModelUtil::containerHandleFromQuery(repoUrl, queryLabel));
    root->setContainers(containers);
    return root;
}

TaskContainerHandle* TasklistModelUtil::containerHandleFromQuery(QString repoUrl, QString queryLabel)
{
    QPointer<TaskContainerHandle> container = new TaskContainerHandle();
    QPointer<Repository> repo = new Repository(container);
    repo->setIdentifier(repoUrl);
    repo->setSummary(repoUrl);
    repo->setUrl(repoUrl);
    container->setRepository(repo);
    container->setIdentifier(queryLabel);
    container->setContainerType(TaskListConstants::CONTAINER_TYPE_QUERY);
    container->setSummary(queryLabel);
    QList<TaskContainerHandle*> containers;
    containers.append(container);
    return container;
}

TaskContainer* TasklistModelUtil::containerFromQuery(BaseTicketItemModel *model, QString repoUrl, QString queryLabel)
{
    QPointer<TaskContainer> container = new TaskContainer();
    QPointer<Repository> repo = new Repository(container);
    repo->setIdentifier(repoUrl);
    repo->setSummary(repoUrl);
    repo->setUrl(repoUrl);
    container->setRepository(repo);
    container->setIdentifier(queryLabel);
    container->setContainerType(TaskListConstants::CONTAINER_TYPE_QUERY);
    container->setSummary(queryLabel);
    container->setSupportsSubTaskCreation(false);
    QList<TaskHandle*> tasks;
    int tickets = model->rowCount(QModelIndex());
    for (int i=0;i<tickets;i++)
    {
        Ticket* ticket = model->ticketAtIndex(model->index(i));
        if (ticket)
        {
            QPointer<TaskHandle> task = new TaskHandle(container);
            task->setActive(false);
            task->setIdentifier(QString::number(ticket->id()));
            task->setTaskKey(task->identifier());
            task->setTaskId(task->identifier());
            task->setRepository(repo);
            task->setSummary(ticket->fieldByName(QString("summary")).toString());
            QString ticketStatus = ticket->fieldByName(QString("status")).toString();
            task->setCompleted(ticketStatus.toLower() == "closed");
            int i = 0;
            QListIterator<TaskHandle*> it (tasks);
            while (it.hasNext() && i < tasks.size())
            {
                TaskHandle *listTask = it.next();
                if (listTask->identifier().toInt() < task->identifier().toInt())
                    i++;
            }
            tasks.insert(i, task);
        }
    }
    container->setTasks(tasks);
    return container;
}

TaskListRoot * TasklistModelUtil::rootFromPreviousRoot(TaskListRoot *previousRoot, QString repoUrl, QString queryLabel)
{
    if (previousRoot)
    {
        QPointer<TaskListRoot> newRoot = new TaskListRoot();
        QList<TaskContainerHandle*> containers;
        QListIterator<TaskContainerHandle*> it (previousRoot->containers());
        while (it.hasNext())
        {
            TaskContainerHandle *previousContainer = it.next();
            if (previousContainer && previousContainer->identifier().toLower() != queryLabel.toLower())
            {
                //copy container only if its not the same as the new one
                TaskContainerHandle *newContainer = TasklistModelUtil::copyContainerHandle(previousContainer, newRoot);
                if (newContainer)
                {
                    //add container at appropriate position
                    QListIterator<TaskContainerHandle*> iter (containers);
                    int i = 0;
                    while (iter.hasNext() && i < containers.size())
                    {
                        TaskContainerHandle* listContainer = iter.next();
                        if (QString::compare(listContainer->identifier(), newContainer->identifier(), Qt::CaseInsensitive) <= 0) {
                            i++;
                        }
                    }
                    containers.insert(i,newContainer);
                }
            }
        }
        //add new container
        if (!queryLabel.isEmpty())
        {
            TaskContainerHandle *newContainer = TasklistModelUtil::containerHandleFromQuery(repoUrl, queryLabel);
            //add container at appropriate position
            QListIterator<TaskContainerHandle*> it (containers);
            int i = 0;
            while (it.hasNext() && i < containers.size())
            {
                TaskContainerHandle* listContainer = it.next();
                if (QString::compare(listContainer->identifier(), newContainer->identifier(), Qt::CaseInsensitive) <= 0) {
                    i++;
                }
            }
            containers.insert(i,newContainer);
        }
        newRoot->setContainers(containers);
        return newRoot;
    }
    else
    {
        return TasklistModelUtil::rootFromQuery(repoUrl, queryLabel);
    }
}

QList<TaskContainer *> TasklistModelUtil::containersFromPreviousContainers(QList<TaskContainer *> previousContainers, BaseTicketItemModel *model, QString repoUrl, QString queryLabel)
{
    QList<TaskContainer*> containers;
    QListIterator<TaskContainer*> it (previousContainers);
    while (it.hasNext())
    {
        TaskContainer *previousContainer = it.next();
        if (previousContainer && previousContainer->identifier().toLower() != queryLabel.toLower())
        {
            //don't copy previous container if new container has same label
            //copy to new container
            QPointer<TaskContainer> newContainer = TasklistModelUtil::copyContainer(previousContainer);
            if (newContainer)
                containers.append(newContainer);
        }
    }
    if (model)
    {
        containers.append(TasklistModelUtil::containerFromQuery(model, repoUrl, queryLabel));
    }
    return containers;
}

Repository* TasklistModelUtil::copyRepository(Repository *toCopy, QObject *parent)
{
    if (!toCopy)
        return 0;
    QPointer<Repository> repo = new Repository(parent);
    repo->setIdentifier(toCopy->identifier());
    repo->setSummary(toCopy->summary());
    repo->setUrl(toCopy->url());
    return repo;
}

TaskContainerHandle* TasklistModelUtil::copyContainerHandle(TaskContainerHandle *toCopy, QObject *parent)
{
    if (!toCopy)
        return 0;
    QPointer<TaskContainerHandle> container = new TaskContainerHandle(parent);
    container->setSummary(toCopy->summary());
    container->setIdentifier(toCopy->identifier());
    container->setRepository(TasklistModelUtil::copyRepository(toCopy->repository(), container));
    container->setContainerType(toCopy->containerType());
    return container;
}

TaskContainer* TasklistModelUtil::copyContainer(TaskContainer *toCopy, QObject *parent)
{
    if (!toCopy)
        return 0;
    QPointer<TaskContainer> container = new TaskContainer(parent);
    container->setSummary(toCopy->summary());
    container->setIdentifier(toCopy->identifier());
    container->setRepository(TasklistModelUtil::copyRepository(toCopy->repository(), container));
    container->setContainerType(toCopy->containerType());
    QListIterator<TaskHandle*> it(toCopy->tasks());
    QList<TaskHandle*> tasks;
    while (it.hasNext())
    {
        TaskHandle *toCopyHandle = it.next();
        if (toCopyHandle)
        {
            TaskHandle *task = TasklistModelUtil::copyTaskHandle(toCopyHandle, container);
            if (task)
                tasks.append(task);
        }
    }
    container->setTasks(tasks);
    return container;
}

TaskHandle* TasklistModelUtil::copyTaskHandle(TaskHandle *toCopy, QObject *parent)
{
    if (!toCopy)
        return 0;
    QPointer<TaskHandle> task = new TaskHandle(parent);
    //ignore parents/children for now
    task->setSummary(toCopy->summary());
    task->setIdentifier(toCopy->identifier());
    task->setRepository(TasklistModelUtil::copyRepository(toCopy->repository(), task));
    task->setTaskId(toCopy->taskId());
    task->setTaskKind(toCopy->taskKind());
    task->setTaskKey(toCopy->taskKey());
    task->setCompletionDate(toCopy->completionDate());
    task->setCreationDate(toCopy->creationDate());
    task->setDueDate(toCopy->dueDate());
    task->setModificationDate(toCopy->modificationDate());
    task->setOwner(TasklistModelUtil::copyPerson(toCopy->owner(), task));
    task->setPriority(toCopy->priority());
    task->setActive(toCopy->active());
    task->setCompleted(toCopy->completed());
    task->setConnectorKind(toCopy->connectorKind());
    task->setTaskUrl(toCopy->taskUrl());
    task->setSynchronizationState(toCopy->synchronizationState());
    task->setTaskImageId(toCopy->taskImageId());
    return task;
}

Person* TasklistModelUtil::copyPerson(Person *toCopy, QObject *parent)
{
    if (!toCopy)
        return 0;
    QPointer<Person> person = new Person(parent);
    person->setName(toCopy->name());
    person->setIdentity(toCopy->identity());
    return person;
}
